package cn.mxz.generator.config;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

import lincen.javase.util.Closer;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class GeneratorConfigImpl implements GeneratorConfig {

	private static final String PROTOCOL_PATH = "protocols";
	private static final String TEMPLET_PATH = "templet";
	private static final String CONFIG_PATH = "config";
	private static final String TAIL = ".temp";
	private List<IClass> clazzs;

	public GeneratorConfigImpl() {

		clazzs = new ArrayList<IClass>();

		File input = new File(PROTOCOL_PATH);
		String[] all = input.list();
		for (String file : all) {
			try {
				readXml(new File(PROTOCOL_PATH + File.separator + file));
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (DocumentException e) {
				e.printStackTrace();
			}
		}

	}

	@SuppressWarnings("unchecked")
	private void readXml(File file) throws MalformedURLException,
			DocumentException {

		SAXReader saxReader = new SAXReader();
		Document document = saxReader.read(file);
		Element e = document.getRootElement();

		String className = e.elementTextTrim("name");
		List<Element> methods = e.elements("method");

		IClass clazz = new ClassImpl(className, "Impl");

		for (Element m : methods) {
			String methodDoc = m.elementTextTrim("doc");
			String returnDoc = m.elementTextTrim("return");

			String id = m.elementTextTrim("id");
			List<String> argsDoc = readArgs(m);

			List<String> backs = readBacks(m); // 这个方法执行后, 返回给客户端的额外数据, 比如强化装备后,
												// 给客户端返回用户战斗力

			String methodText = m.getTextTrim();

			long mId = id != null ? new Long(id) : MethodIDManager
					.getMethodId();

			IMethod method = new MethodImpl(methodText, methodDoc, returnDoc,
					argsDoc, backs, mId, this);

			clazz.addMethod(method);
			MethodIDManager.nextMethod();
		}
		add(clazz);
		MethodIDManager.nextClass();
	}

	private List<String> readBacks(Element m) {
		return readStrings(m, "back");
	}

	private void add(IClass clazz) {
		this.clazzs.add(clazz);
	}

	@SuppressWarnings("unchecked")
	private List<String> readStrings(Element m, String node) {
		List<String> args = new ArrayList<String>();
		List<Element> as = m.elements(node);
		for (Element element : as) {
			args.add(element.getTextTrim());
		}
		return args;
	}

	private List<String> readArgs(Element m) {
		return readStrings(m, "args");
	}

	@Override
	public List<IClass> getClazzs() {
		return clazzs;
	}

	@Override
	public String getTemplet(String templetFileName) {
		InputStreamReader is = null;
		try {
			File f = new File(TEMPLET_PATH + File.separator + templetFileName
					+ TAIL);

			is = new InputStreamReader(new FileInputStream(f), "utf8");

			BufferedReader br = new BufferedReader(is);

			StringBuffer sb = new StringBuffer();
			while (true) {
				String line = br.readLine();
				if (line == null) {
					break;
				}

				sb.append(line + "\r");
			}

			return sb.toString();

		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			Closer.close(is);
		}
	}

	@Override
	public FileUtil getFileUtil(String filePath) {
		return new FileUtilImpl(filePath);
	}

	@Override
	public String getNodeText(String xmlNodeSpliteByComma) {
		String[] split = xmlNodeSpliteByComma.split("\\.");
		SAXReader saxReader = new SAXReader();
		Document document;
		try {
			document = saxReader.read(new File(CONFIG_PATH + File.separator
					+ "config.xml"));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		Element root = document.getRootElement();

		Element element = root;

		try {
			for (int i = 0; i < split.length; i++) {
				element = element.element(split[i].trim());
			}
			return element.getTextTrim();
		} catch (NullPointerException e) {
			return null;
		}
	}

	@Override
	public IInterface getInterface(String className) {
		for (IClass c : clazzs) {
			if (c.getInterface().getName().equals(className)) {
				return c.getInterface();
			}
		}
		throw new IllegalArgumentException("接口" + className + "没有找到");
	}
}
